//***************************************************************
//
// Created BY: JESSE SAHOTA
// COURSE: CPSC 589
//
//***************************************************************
#include "Vector.h"
//+++++++++++++++++++++++++++++
//Part A: Constructors/Destructors
//+++++++++++++++++++++++++++++
Vector :: ~Vector(){

}
//+++++++++++++++++++++++++++++
//Part B: Operators
//+++++++++++++++++++++++++++++
//SIMPLE POINT/VECTOR MATH OPERATIONS
//return a point or vector, by add between two common points/Vector
Vector Vector::operator +(const Vector & a) const
{
    return Vector(x+a.x, y+a.y, z+a.z);
}

//return a point or vector, by subtracting between two common points/Vector
Vector Vector::operator -(const Vector & a) const
{
    return Vector(x-a.x, y-a.y, z-a.z);
}

//return a inverse vector or point
Vector Vector::operator -() const
{
    return Vector(-x, -y, -z);
}

//return a point or vector, by dividing by double factor
Vector Vector::operator /(const double & s) const
{
    return Vector(x/s, y/s, z/s);
}

//return a point or vector by multiply by a double factor
Vector operator *(const double & s, const Vector &A)
{
    Vector point = A;
    return Vector(s * point.getX(), s * point.getY(), s * point.getZ());
}
Vector operator *(const Vector & A, const double & s){
    return(s*A);
}
//to add a point or a vector to the current one
void Vector::operator +=(const Vector & a) {
    x += a.x;
    y += a.y;
    z += a.z;

}
//to set a point or a vector
void Vector::operator =(const Vector & a) {
    x = a.x;
    y = a.y;
    z = a.z;

}

//+++++++++++++++++++++++++++++
//Part C: Getters And Setters
//+++++++++++++++++++++++++++++
//SETTERS
void Vector::setX(const double & _x){
    x= _x;
}
void Vector::setY(const double & _y){
    y = _y;
}

void Vector::setZ(const double & _z){
    z = _z;
}

//GETTERS
double Vector::getX() const{
    return x;
}

double Vector::getY() const{
    return y;
}

double Vector::getZ() const{
    return z;
}

//+++++++++++++++++++++++++++++
//Part D: Point/Vector Operations
//+++++++++++++++++++++++++++++
// cross product with another vector
Vector Vector::cross(const Vector & v){
    return( Vector(y *v.getZ() - z * v.getY(), z * v.getX() - x * v.getZ(), x*v.getY() - y *v.getX()));
}

//dot product with another vector
double Vector::dotProduct(const Vector & u)const{
    return(u.x * x)+ (u.y * y) + (u.z * z);
}
//length of vector is square root of the vector dot product.
double Vector::length()const{
    return(sqrt(((x*x)+ (y*y) +(z*z))));
}

//normalize the vector by vector by divide by the length of the vector
Vector Vector::normalize() const{
    double length = sqrt(((x*x)+ (y*y) +(z*z)));
    if(length == 0)
    {
        length = 1;
    }
    double lenInv = 1/length;
    return Vector(x * lenInv, y * lenInv, z * lenInv);
}
void Vector::unit(){
    (*this) = this->normalize();
}

double Vector::getDistance(const Point3d &P)const{
    return(((*this)-P).length());
}

void Vector::glv(){
    glVertex3d(this->getX(), this->getY(), this->getZ());
}
